/*
 * DevicesLed.c
 *
 *      Author: Honrun
 */

#include "CSU8RP3216.h"
#include "stdint.h"
#include "DevicesSoftTimer.h"
#include "DevicesLed.h"



static LedInfoType st_typeLedInfo;

/* 周期调用计数（调用频率为10k） */
volatile static uint32_t st_uiLedTickCnt;

static SoftTimerTypeDef g_typeTimerLED;



void vLedInit(void)
{
    /*
        PT 数据标志位
    */
    PT5_1 = 0;

    /*
        PT5EN 输入/输出控制标志
        0: 定义为输入口
        1: 定义为输出口
    */
    PT5EN_1 = 1;

    /*
        PT5PU 上拉电阻使能标志
        0: 断开上拉电阻
        1: 使用上拉电阻
    */
    PT5PU_1 = 0;

    /*
        PT5CON 模拟/数字端口使能标志
        0: 定义为数字口
        1: 定义为模拟口
    */
    PT50OD = 0;
    PT51OD = 0;
    PT5CON0 = 0;

    /*
        PT 数据标志位
    */
    PT5_2 = 0;

    /*
        PT5EN 输入/输出控制标志
        0: 定义为输入口
        1: 定义为输出口
    */
    PT5EN_2 = 1;

    /*
        PT5PU 上拉电阻使能标志
        0: 断开上拉电阻
        1: 使用上拉电阻
    */
    PT5PU_2 = 0;

    /*
        PT5CON 模拟/数字端口使能标志
        0: 定义为数字口
        1: 定义为模拟口
    */
    PT50OD = 0;
    PT51OD = 0;
    PT5CON0 = 0;

    vLedOpen(LED_ALL);

    st_typeLedInfo.white.channel = LED_WHITE;
    st_typeLedInfo.blue.channel  = LED_BLUE;

    vLedSetStatus(LED_ALL, LED_FLASH_SLOW_CIRCULAR, 10);

    cSoftTimerSetMs(&g_typeTimerLED, 100, softTimerOpen);
}

void vLedOpen(uint16_t usChannel)
{
    if(usChannel & LED_WHITE)
        PT5_1 = 1;
    if(usChannel & LED_BLUE)
        PT5_2 = 1;
}

void vLedClose(uint16_t usChannel)
{
    if(usChannel & LED_WHITE)
        PT5_1 = 0;
    if(usChannel & LED_BLUE)
        PT5_2 = 0;
}

void vLedRevesal(uint16_t usChannel)
{
    if(usChannel & LED_WHITE)
        PT5_1 = !PT5_1;
    if(usChannel & LED_BLUE)
        PT5_2 = !PT5_2;
}

/*
 * Return:      void
 * Parameters:  usChannel: LED通道; usChannel: 状态; usChannel: 闪烁次数/或者占空比;
 * Description: 设置LED状态
 */
void vLedSetStatus(uint16_t usChannel, LedStateEnum enumStatus, uint8_t ucFlashCnt_or_Duty)
{
    if(usChannel & LED_WHITE)
    {
        st_typeLedInfo.white.state = enumStatus;
        st_typeLedInfo.white.flashCnt = ucFlashCnt_or_Duty * 2 + 1;
    }
    if(usChannel & LED_BLUE)
    {
        st_typeLedInfo.blue.state = enumStatus;
        st_typeLedInfo.blue.flashCnt = ucFlashCnt_or_Duty * 2 + 1;
    }
}

/*
 * Return:      void
 * Parameters:  *ptypeLed: LED信息结构体
 * Description: LED状态刷新
 */
void vLedStateMachine(LedType *ptypeLed)
{
    switch(ptypeLed->state)
    {
        /* 关闭 */
        case LED_DISABLE:
            vLedClose(ptypeLed->channel);
            ptypeLed->state = LED_IDLE;
            break;

        /* 常亮 */
        case LED_ENABLE:
            vLedOpen(ptypeLed->channel);
            ptypeLed->state = LED_IDLE;
            break;

        /* 循环快闪 */
        case LED_FLASH_SLOW_CIRCULAR:
        /* 快闪后关闭 */
        case LED_FLASH_SLOW_DISABLE_CNT:
        /* 快闪后常亮 */
        case LED_FLASH_SLOW_ENABLE_CNT:
            if((st_uiLedTickCnt % 5) == 0)
            {
                vLedRevesal(ptypeLed->channel);

                if((ptypeLed->state != LED_FLASH_SLOW_CIRCULAR) && (ptypeLed->state != LED_FLASH_FAST_CIRCULAR) && ((ptypeLed->flashCnt--) <= 0))
                {
                    ptypeLed->state = ((ptypeLed->state == LED_FLASH_SLOW_ENABLE_CNT) || (ptypeLed->state == LED_FLASH_FAST_ENABLE_CNT)) ? LED_ENABLE : LED_DISABLE;
                }
            }
            break;

        /* 循环慢闪 */
        case LED_FLASH_FAST_CIRCULAR:
        /* 慢闪后关闭 */
        case LED_FLASH_FAST_DISABLE_CNT:
        /* 慢闪后常亮 */
        case LED_FLASH_FAST_ENABLE_CNT:
            if((st_uiLedTickCnt % 10) == 0)
            {
                vLedRevesal(ptypeLed->channel);

                if((ptypeLed->state != LED_FLASH_SLOW_CIRCULAR) && (ptypeLed->state != LED_FLASH_FAST_CIRCULAR) && ((ptypeLed->flashCnt--) <= 0))
                {
                    ptypeLed->state = ((ptypeLed->state == LED_FLASH_SLOW_ENABLE_CNT) || (ptypeLed->state == LED_FLASH_FAST_ENABLE_CNT)) ? LED_ENABLE : LED_DISABLE;
                }
            }
            break;

        default : break;
    }
}

void vLedMachine(void)
{
    if(enumSoftTimerGetState(&g_typeTimerLED) == softTimerOver)
    {
        cSoftTimerReload(&g_typeTimerLED);

        /* 所有LED使用同一个状态机变量，以方便实现一致的闪烁步调 */
        ++st_uiLedTickCnt;

        /* 遍历全部 */
        vLedStateMachine(&st_typeLedInfo.white);
        vLedStateMachine(&st_typeLedInfo.blue);
    }
}

LedInfoType *ptypeLedGetInfo(void)
{
    return &st_typeLedInfo;
}
